/*******************************************************************************
 * Venice Noise Android Application
 * Copyright (C) 2011  Worcester Polytechnic Institute, Wesley Ripley
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; version 2
 * of the License
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 * 
 * If you plan to use or modify any of this code please contact Fabio Carrera (carrera.fabio@gmail.com)
 * Also please attribute any code used in the final product to the developers. 
 * 
 * Author: Wesley Ripley (wripley@wpi.edu) 
 *******************************************************************************/

package org.venicenoise.app;

import java.io.File;
import java.util.EnumSet;
import java.util.Set;

import org.venicenoise.app.location.LocationService;


/**
 * A data structure class representing all of the
 * pieces that make up one noise data point
 * 
 * @author Wesley Ripley
 * @version 12/6/2011
 */
public class NoiseData {
	
	/**
	 * The type value that should be submitted to the web page if the
	 * submission is a public submission. Corresponds with Type.PUBLIC
	 */
	private final static short PUBLIC_MODE = 0;
	
	/**
	 * The type value that should be submitted to the web page if the
	 * submission is official recorded field data. Corresponds with Type.OFFICIAL
	 */
	private final static short OFFICIAL_MODE = 1;
	/**
	 * The type value that should be submitted to the web page if the
	 * submission is a test submission. Corresponds with Type.TEST
	 */
	private final static short TEST_MODE = 2;
	
	/**
	 * An enum defining the different types of data.
	 * @author Wesley Ripley
	 * @version 12/5/2011
	 */
	public enum Type {
		/**
		 * Public data from any normal person using the App
		 */
		PUBLIC(PUBLIC_MODE),
		/**
		 * Official data taken by people who created this App for
		 * use with their project, and any subsequent groups using this
		 * App for their project.
		 */
		OFFICIAL(OFFICIAL_MODE), 
		/**
		 * Test data that is not real data but only used to test
		 * the functionality of the App
		 */
		TEST(TEST_MODE);

		private final short value;

		private Type(short value) {
			this.value = value;
		}

		/**
		 * Get the value associated with this type.
		 * For use when submitting to the web.
		 * @return
		 * 		the value associated with this type
		 */
		public short getValue() {
			return value;
		}
		
		/**
		 * Go from a value from the web to a Type
		 * @param value
		 * 		The value representing the type from the web
		 * @return
		 * 		the Type with the value that was given. 
		 * 		Null if there is no Type with the given value
		 */
		public static Type typeFromValue(short value)
		{
			//this function will work even when new types are added
			final Set<Type> allTypes = EnumSet.allOf(Type.class);//get all of the different Types
			for(Type type : allTypes)
			{	//loop through them until you find one with the right value
				if(type.getValue() == value)
				{
					return type;
				}
			}
			return null;
		}
	};
	
	private final LocationService location;
	private final double spl;
	private final double leq;
	private final double sel;
	private final String description;
	private final File audioFile;
	private final File photoFile;
	private final long timestamp;
	private final Type type;
	
	/**
	 * Constructor for NoiseData
	 * @param location
	 * 		The location service that will give the location the data was taken
	 * @param spl
	 * 		The recorded Sound Pressure Level (SPL)
	 * @param leq
	 * 		The recorded Equivalent Sound Pressure Level (Leq)
	 * @param sel
	 * 		The recorded Sound Exposure Level (SEL)
	 * @param description
	 * 		A description of the data
	 * @param audioFile
	 * 		The audio file the noise was recorded to
	 * @param photoFile
	 * 		The image file where a picture of the noise source was stored
	 * @param timestamp
	 * 		The time the data was taken, in Unix time, number of seconds since Jan 1, 1970 GMT
	 * @param type
	 * 		The type of this data point. Should be one of the 
	 */
	public NoiseData(LocationService location, double spl, double leq, double sel, String description, File audioFile, File photoFile, long timestamp,  Type type)
	{
		this.location = location;
		this.spl = spl;
		this.leq = leq;
		this.sel = sel;
		this.description = description;
		this.audioFile = audioFile;
		this.photoFile = photoFile;
		this.timestamp = timestamp;
		this.type = type;
	}
	
	/**
	 * Get the location service to use to get the location this data point was taken at
	 * @return
	 * 		the LocationService
	 */
	public LocationService getLocationService() {
		return location;
	}

	/**
	 * Get the Sound Pressure Level (SPL) of this data point
	 * @return
	 * 		the SPL value
	 */
	public double getSPL() {
		return spl;
	}

	/**
	 * Get the Equivalent Sound Pressure Level (Leq) of this data point
	 * @return
	 * 		the Leq value
	 */
	public double getLeq() {
		return leq;
	}

	/**
	 * Get the Sound Exposure level (SEL) of this data point
	 * @return
	 * 		the SEL value
	 */
	public double getSEL() {
		return sel;
	}

	/**
	 * Get the description of this data point
	 * @return
	 * 		the description
	 */
	public String getDescription() {
		return description;
	}

	/**
	 * Get the audio file of this data point
	 * @return
	 * 		the audio file
	 */
	public File getAudioFile() {
		return audioFile;
	}
	
	/**
	 * Get the image file of the photo taken for this data pint
	 * @return
	 * 		the image file
	 */
	public File getPhotoFile()
	{
		return photoFile;
	}
	
	/**
	 * Get the time this data point was taken.
	 * @return
	 * 		the time, in Unix time, number of seconds since Jan 1, 1970 GMT
	 */
	public long getTimestamp()
	{
		return timestamp;
	}
	
	/**
	 * Get the type of this data point
	 * @return
	 * 		the type
	 */
	public Type getType()
	{
		return type;
	}
	
}
